<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>

    <script>
      // reflect 反射
      // 一句话就是调用对象的基本方法
      // 因为js对象很多方法是没有暴露出来的，通过封装好的语法调用就好，es6通过reflect可以调用
      let obj = {
        a:1,
        b:2,
         get c() {
            return this.a + this.b;
         }
      }

      console.log(obj.c);// 当我们使用语法读取对象属性，实际上执行时候会执行一个被封装过后的方法，然后在封装方法中调用对象的基本方法
      console.log(Reflect.get(obj,'c'));// 调用对象的基本方法
      console.log(Reflect.get(obj,'c',{a:10,b:30}));// 调用对象的基本方法,第三个参数receiver指定this指向，返回40

      // 获取对象所有属性
      // 先添加一个不可枚举的属性
      Object.defineProperty(obj,'d',{
        value:4,
        enumerable:false
      })
      console.log(Object.keys(obj));// 获取对象所有属性，但是调用的封装方法会过滤掉不可枚举的
      console.log(Reflect.ownKeys(obj));// t通过直接调用基本方法获取，获取对象所有属性


      // 代理例子

      const proxy = new Proxy(obj,{
        get(target,key,receiver) {
          console.log('get',target,key,receiver);
          // 如果不穿receiver，获取c的时候，此时c的this是target,也就是原始对象obj,而不是代理对象proxy
           // 所以获取c的时候，只监听到了c,没有监听到a,b
        //   return Reflect.get(target,key);   
          return Reflect.get(target,key,receiver);  
        }
      })

      console.log(proxy.c);// 调用对象的基本方法
    


    </script>
    
</body>
</html>